﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProgNetComponents.Data;
using System.Data;
using ProgNetComponents.Classes;
using ProgNetComponents.Collections;
using ProgNetComponents.Interfaces;
using System.Collections;

namespace ProgNetComponentsDx.Data
{
    public static class SelectDataCache
    {
        public static void TestDataLng()
        {
            DataManager m = ManagerCreator.CreateManager();
            var tables = m.SchemaChecker.GetTables();
            
            foreach (var table in tables)
            {
                foreach (var col in m.SchemaChecker.GetTableColumns(table))
                    Language.ProgNetLanguage.sGetString(col);
            }
            foreach (var v in RegisteredSelectData)
            {
                if (v.Value is SelectData)
                {
                    Language.ProgNetLanguage.sGetString((v.Value as SelectData).Name);
                }
            }
        }

        public static SelectDataManagerCreator ManagerCreator
        {
            get;
            set;
        }

        private static NamedObjectCollection _RegisteredSelectData = new NamedObjectCollection();
        public static NamedObjectCollection RegisteredSelectData
        {
            get { return _RegisteredSelectData; }
        }

        public static bool IsTheSameSelectData(object option1, object option2)
        {
            return GetKey(option1) == GetKey(option2);
        }
        public static string GetKey(object optionId)
        {
            string key = "";
            if (optionId != null && optionId.GetType().IsEnum)
            {
                key = optionId.GetType().FullName;
                key = key.Replace("+", ".").XReplace("_Group\\.", ".") + ".";
            }
            key += optionId.AsString();
            return key;
        }

        private static Dictionary<string, DataManager> Managers = new Dictionary<string, DataManager>();

        public static void RegisterGroups(IList groups, Type NamesType)
        {
            string key = NamesType.FullName + ".";
            foreach (INamedGroup g in groups)
            {
                RegisterGroups(g, key + g.Name);
            }
        }
        private static void RegisterGroups(INamedGroup group, string key)
        {
            RegisterItems(group.Items, key);
            foreach (INamedGroup g in group.Groups)
            {
                RegisterGroups(g, key + "." + g.Name);
            }
        }
        private static void RegisterItems(IList items, string key)
        {
            foreach (INamedObject o in items)
                RegisteredSelectData.Add(key + "." + o.Name, o);
        }

        public static SelectData GetSelectData(object selectDataId)
        {
            string name = GetKey(selectDataId);
            if (RegisteredSelectData.Contains(name))
                return RegisteredSelectData[name].Value as SelectData;
            return null;
        }
        public static DataManager GetManager(object selectDataId)
        {
            string selectDataName = GetKey(selectDataId);

            if (Managers.ContainsKey(selectDataName))
            {
                return Managers[selectDataName];
            }
            else
            {
                SelectData data = GetSelectData(selectDataId);

                if (data != null && ManagerCreator != null)
                {
                    if (data.RecordSelect.Count > 0)
                    {
                        DataManager m = ManagerCreator.CreateManager();
                        Managers.Add(selectDataName, m);
                        return m;
                    }
                }
            }
            return null;
        }

        public static void PrepareSelectData(object selectDataId, params DataSet[] datasets)
        {
            if (datasets != null)
            {
                DataManager m = GetManager(selectDataId);
                SelectData data = GetSelectData(selectDataId);

                if (m != null && data != null)
                {
                    if (m.TableDefsCount == 0)
                    {
                        foreach (RecordSelectStruct s in data.RecordSelect)
                        {
                            foreach (DataSet ds in datasets)
                            {
                                if (ds.Tables.Contains(s.DataSetTableName))
                                    m.AddTableDef(ds.Tables[s.DataSetTableName], s.DataBaseTableName, s.SelectString);
                            }
                        }
                    }
                }
            }
        }

        public static void PrepareSelectData(object selectDataId, params DataTable[] datatables)
        {
            if (datatables != null)
            {
                DataManager m = GetManager(selectDataId);
                SelectData data = GetSelectData(selectDataId);
                
                if (m != null && data != null)
                {
                    if (m.TableDefsCount == 0)
                    {
                        Dictionary<string, DataTable> dic = new Dictionary<string, DataTable>();
                        foreach (DataTable dt in datatables)
                        {
                            dic.Add(dt.TableName, dt);
                        }
                        foreach (RecordSelectStruct s in data.RecordSelect)
                        {
                            if (dic.ContainsKey(s.DataSetTableName))
                                m.AddTableDef(dic[s.DataSetTableName], s.DataBaseTableName, s.SelectString);
                        }
                    }
                }
            }
        }

        public static bool FillData(DataSet ds, object selectDataId, params NamedObject[] parameters)
        {
            PrepareSelectData(selectDataId, ds);

            DataManager m = GetManager(selectDataId);
            if (m != null)
            {
                bool b = m.FillDataSet(ds, parameters);
                if(!b)
                    m.LastException.Log();
                return b;
            }
            return false;
        }

        public static bool UpdateData(DataSet ds, object selectDataId)
        {
            PrepareSelectData(selectDataId, ds);

            DataManager m = GetManager(selectDataId);
            if (m != null)
            {
                bool b = m.UpdateDataSet(ds);
                if (!b)
                    m.LastException.Log();
                return b;
            }
            return false;
        }

    }
}
